package com.bs.service;

import com.bs.domain.ServiceInfo;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: rui xu
 * @Date: 2019/4/11 9:51
 */

@Service
public class DeployDashService {


    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    private String startTime;
    private String endTime;
    private String active;
    private long interval;
    private String code;

    /**
     * 上线排行
     *
     * @return
     */
    private SearchResponse getOnlineSortResponse() {
        String index = "logstash-*-" + active + "-deploy-*";
        Client client = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.termQuery("category", "DEPLOY"))
            .must(QueryBuilders.termQuery("deploy_op", "tmboot"))
            .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00"));
        TermsBuilder deployNameAgg = AggregationBuilders.terms("deploy_name").field("deploy_name").size(10);
        TermsBuilder partitionAgg = AggregationBuilders.terms("partition").field("partition");

        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes("log");
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(deployNameAgg.subAggregation(partitionAgg))
            .execute()
            .actionGet();
    }


    public List<ServiceInfo> onlineSortService(String startTime, String endTime, String active) {
        this.startTime = startTime;
        this.endTime = endTime;
        this.active = active;
        SearchResponse response = getOnlineSortResponse();
        ArrayList<ServiceInfo> list = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms deployName = (StringTerms) response.getAggregations().getAsMap().get("deploy_name");
            Iterator<Terms.Bucket> iterator = deployName.getBuckets().iterator();
            while (iterator.hasNext()) {
                HashMap<String, Long> hashMap = new HashMap<>();
                Terms.Bucket next = iterator.next();
                String svcName = next.getKeyAsString();
                StringTerms partitionAgg = (StringTerms) next.getAggregations().getAsMap().get("partition");
                for (Terms.Bucket bucket : partitionAgg.getBuckets()) {
                    String partition = String.valueOf(bucket.getKey());
                    long count = bucket.getDocCount();
                    hashMap.put(partition, count);

                }
                ServiceInfo serviceInfo = new ServiceInfo(svcName, hashMap);
                list.add(serviceInfo);
            }
        }
        return list;

    }

    /**
     * 上线趋势
     *
     * @return
     */
    private SearchResponse getOnlineTrendResponse() {
        String index = "logstash-*-" + active + "-deploy-*";
        Client client = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.termQuery("category", "DEPLOY"))
            .must(QueryBuilders.termQuery("deploy_op", "tmboot"))
            .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00"));
        DateHistogramBuilder timeAgg = AggregationBuilders.dateHistogram("date_histogram").field("@timestamp").interval(interval).minDocCount(1).timeZone("+08:00");
        TermsBuilder partitionAgg = AggregationBuilders.terms("partition").field("partition").size(20);
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes("log");
        return searchRequestBuilder
         .setSize(0)
            .setQuery(builder)
            .addAggregation(partitionAgg.subAggregation(timeAgg))
            .execute()
            .actionGet();
    }


    public List<ServiceInfo> onlineTrendService(String startTime, String endTime, long interval, String active) {
        this.startTime = startTime;
        this.endTime = endTime;
        this.active = active;
        this.interval = interval;
        SearchResponse response = getOnlineTrendResponse();
        ArrayList<ServiceInfo> list = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms deployName = (StringTerms) response.getAggregations().getAsMap().get("partition");
            Iterator<Terms.Bucket> iterator = deployName.getBuckets().iterator();
            while (iterator.hasNext()) {
                HashMap<String, Long> hashMap = new HashMap<>();
                Terms.Bucket next = iterator.next();
                String partition = next.getKeyAsString();
                Histogram agg = next.getAggregations().get("date_histogram");
                for (Histogram.Bucket bucket : agg.getBuckets()
                    ) {
                    String time = bucket.getKeyAsString();
                    long count = bucket.getDocCount();
                    hashMap.put(time, count);
                }
                ServiceInfo serviceInfo = new ServiceInfo(partition, hashMap);
                list.add(serviceInfo);
            }
        }

        return list;
    }


}
